package com.lblin.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousChannelGroup;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

public class ClientSocket {

	public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
		new ClientSocket().init();
	}

	public void init() throws IOException {
		// 创建通道组 （线程池）
		AsynchronousChannelGroup group = AsynchronousChannelGroup.withFixedThreadPool(2, new ThreadFactory() {

			private byte index = 0;

			public Thread newThread(Runnable r) {
				// TODO Auto-generated method stub
				return new Thread(r, "lblin-aio-clientThread-" + (++index));
			}
		});
		AsynchronousChannelGroup group1 = AsynchronousChannelGroup.withFixedThreadPool(2, new ThreadFactory() {

			private byte index = 0;

			public Thread newThread(Runnable r) {
				// TODO Auto-generated method stub
				return new Thread(r, "lblin-aio-clientThread-" + (++index));
			}
		});
		AsynchronousChannelGroup group2 = AsynchronousChannelGroup.withFixedThreadPool(2, new ThreadFactory() {

			private byte index = 0;

			public Thread newThread(Runnable r) {
				// TODO Auto-generated method stub
				return new Thread(r, "lblin-aio-clientThread-" + (++index));
			}
		});

		final AsynchronousSocketChannel client = AsynchronousSocketChannel.open(group);
		final AsynchronousSocketChannel client1 = AsynchronousSocketChannel.open(group1);
		final AsynchronousSocketChannel client2 = AsynchronousSocketChannel.open(group2);

		connect(client);
		connect(client1);
		connect(client2);

		// client.close();
		// group.shutdown();
	}

	private void connect(final AsynchronousSocketChannel client) {
		// TODO Auto-generated method stub
		client.connect(new InetSocketAddress("127.0.0.1", 8080), null, new CompletionHandler<Void, Object>() {

			ByteBuffer readBuffer = ByteBuffer.allocateDirect(1024);

			volatile int num = 0;

			public void completed(Void result, Object attachment) {

				writeToServer();

			}

			private void readFromServer() {
				readBuffer.clear();
				client.read(readBuffer, "ceshi", new CompletionHandler<Integer, String>() {

					public void completed(Integer result, String attachment) {

						TimerTaskDemo.recivePacket.addAndGet(result);
						TimerTaskDemo.time.incrementAndGet();
						//
						// readBuffer.flip();
						//
						// CharsetDecoder decoder =
						// Charset.forName("UTF-8").newDecoder();
						//
						// try {
						// System.out.println("接收到服务端返回的信息："+
						// decoder.decode(readBuffer).toString());
						// } catch (CharacterCodingException e) {
						// // TODO Auto-generated catch block
						// e.printStackTrace();
						// }
						//
						// try {
						// System.out.println("休息一秒..");
						// Thread.sleep(1000);
						// } catch (InterruptedException e) {
						// // TODO Auto-generated catch block
						// e.printStackTrace();
						// }

						writeToServer();

					}

					public void failed(Throwable exc, String attachment) {
						// TODO Auto-generated method stub
						exc.printStackTrace();
					}
				});
			}

			private void writeToServer() {

				// TODO Auto-generated method stub
				// System.out.println("客户端连接成功！当前处理线程为："+Thread.currentThread().getName());

				try {
					// System.out.println("客户端发送：hello world!"+(++num));
					ByteBuffer bf = ByteBuffer.wrap(("hello world!" + num).getBytes());
					client.write(bf).get();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (ExecutionException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				readFromServer();
			}

			public void failed(Throwable exc, Object attachment) {
				// TODO Auto-generated method stub
				exc.printStackTrace();
			}
		});
	}
}
